<template>
  <div>
    <el-card>
      <h1 style="width: 20%; margin: auto">算法介绍</h1>
      <p style="font-size: large">
        主成分分析（Principal Component Analysis，PCA）是一种经典的无监督降维方法，旨在通过线性变换将高维数据投影到低维空间，同时保留数据中的主要信息。其核心思想是最大化数据的方差，通过找到数据中变化最大的方向（主成分）来简化数据结构。第一主成分（PC1）包含数据中最大的方差，后续主成分依次递减且与先前成分正交。
      </p>
      <el-table
        :data="tableData"
        style="width: 100%">
        <el-table-column
          prop="name"
          label="算法分析指标"
          width="180">
        </el-table-column>
        <el-table-column
          prop="mean"
          label="定义"
          width="250">
        </el-table-column>
        <el-table-column
          prop="count"
          label="算式">
        </el-table-column>
        <el-table-column
          prop="earn"
          label="意义">
        </el-table-column>
      </el-table>
    </el-card>

    <el-card>
      <h1 style="width: 20%; margin: auto">数据集选择</h1>
      <el-select v-model="courseSelect" filterable placeholder="请选择课程" style="width: 20%; margin: 2%">
        <el-option
          v-for="item in courseOptions"
          :key="item.subId"
          :label="item.subName"
          :value="item.subId">
        </el-option>
      </el-select>
      <el-button type="primary" @click="majorAnalyse" style="width: 10%; margin: 2%">开始分析</el-button>
    </el-card>

    <el-card v-if="show">
      <h1 style="width: 20%; margin: auto">分析图表</h1>
      <div
        ref="myChart"
        id="myChart"
        :style="{ width: '800px', height: '800px' }"
        style="margin: auto"
      >
      </div>
    </el-card>

    <el-card v-if="show">
      <h1 style="width: 20%; margin: auto">分析结果说明</h1>
      <el-table
        :data="valuesTable"
        style="width: 100%"
      >
        <el-table-column
          prop="special"
          label="问题名称"
          style="width: 50%; margin: auto"
        />
        <el-table-column
          prop="specialRange"
          label="贡献率"
          sortable
          style="width: 50%; margin: auto"
        />
      </el-table>
    </el-card>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import axios from 'axios'

export default {
  data() {
    return {
      courseOptions: [],
      courseSelect: '',
      dataArray: [0, 0, 0, 0, 0, 0],
      dataArray2: [0, 0, 0, 0, 0, 0],
      data: [],
      dataShow: [],
      valuesTable: [],
      tableData: [
        {
          name: '特征值',
          mean: '在PCA中，特征值用于量化数据在不同主成分方向上的方差大小。',
          count: '协方差矩阵 Σ 定义为 Σ = X‘T * X / n - 1;  协方差矩阵的特征值 λ 满足：det(Σ − λI) = 0',
          earn: '特征值越大说明数据在对应主成分方向上的离散程度越高，信息量越大。'
        },
        {
          name: '载荷',
          mean: '载荷是原始变量与主成分之间的相关系数，表示每个原始变量对主成分的贡献强度。',
          count: 'Loading = v * 根号下λ ',
          earn: '绝对值越大，表示该变量对主成分的贡献越显著。例如，若某变量在PC1上的载荷为0.8，而另一变量为0.3，则前者对PC1的解释力更强'
        },
        {
          name: '贡献率',
          mean: '在PCA中，特征值用于量化数据在不同主成分方向上的方差大小。',
          count: '贡献率 = λ / Σ λ',
          earn: '通常选择累计贡献率超过80%~95%的前k个主成分。'
        }
      ],
      show: false
    }
  },
  methods: {
    async getCourseOptions() {
      await axios.get('http://localhost:8080/course/get_all').then((res) => {
        for (let i = 0; i < res.data.data.length; i++) {
          this.courseOptions[i] = {
            subName: '',
            subId: ''
          }
          this.courseOptions[i].subName = res.data.data[i].subName
          this.courseOptions[i].subId = res.data.data[i].subId
        }
        this.courseOptions[this.courseOptions.length - 1].subName = 'ALL'
        this.courseOptions[this.courseOptions.length - 1].subId = 'ALL'
        this.courseSelect = '请选择课程'
      })
    },
    async getPCAData() {
      if (this.courseSelect === '请选择课程' || this.courseSelect === 'ALL') {
        this.courseSelect = null
      }

      console.log(this.courseSelect)
      const params = new URLSearchParams()
      params.append('subId', this.courseSelect)

      await axios.post('http://localhost:8080/pca/get_pca_details', params, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded' // 必须指定 Content-Type
        }
      }).then((res) => {
        console.log(res)
        // 未查询到相关数据进行提示
        if (res.data.success === false) {
          this.$message.error('未查询到相关数据')
          this.show = false
          return
        } else {
          this.show = true
        }

        this.data[0] = {
          value: 0,
          name: '价值引领（课程教学具有感染力，帮助我树立正确的“三观”，培养了我的认知能力，激发了我课程学习的积极性。）'
        }
        this.data[1] = {
          value: 0,
          name: '教学内容（我很清楚本课程的学习目标、安排和要求，教学资源丰富，重难点突出，我能接触到专业前沿知识和新成果。）'
        }
        this.data[2] = {
          value: 0,
          name: '教学方法（运用信息化教学工具，教学形式多样，讲授清楚，注重互动，激发我自主学习、思考与创新。）'
        }
        this.data[3] = {
          value: 0,
          name: '教学组织（关爱学生，严格要求，课堂有任务，有答疑解惑，有恰当的作业布置。）'
        }
        this.data[4] = {
          value: 0,
          name: '课程考核（采用考试、小论文、报告、作业等多种形式开展课程考核，平时成绩组成多样，评分公平。）'
        }
        this.data[5] = {
          value: 0,
          name: '学习收获（这门课程使我知识、能力、素养得到全面提升，学习收获大。）'
        }
        console.log(res)
        this.data[0].value = res.data.data.values[0]
        this.data[1].value = res.data.data.values[1]
        this.data[2].value = res.data.data.values[2]
        this.data[3].value = res.data.data.values[3]
        this.data[4].value = res.data.data.values[4]
        this.data[5].value = res.data.data.values[5]

        this.dataArray[0] = res.data.data.values[0]
        this.dataArray[1] = res.data.data.values[1]
        this.dataArray[2] = res.data.data.values[2]
        this.dataArray[3] = res.data.data.values[3]
        this.dataArray[4] = res.data.data.values[4]
        this.dataArray[5] = res.data.data.values[5]

        this.dataArray2[0] = res.data.data.valuesContribution[0]
        this.dataArray2[1] = res.data.data.valuesContribution[1]
        this.dataArray2[2] = res.data.data.valuesContribution[2]
        this.dataArray2[3] = res.data.data.valuesContribution[3]
        this.dataArray2[4] = res.data.data.valuesContribution[4]
        this.dataArray2[5] = res.data.data.valuesContribution[5]

        for (let i = 0; i < 6; i++) {
          this.dataShow[i] = {
            index: i,
            value: this.data[i].value,
            name: this.data[i].name
          }
        }

        this.valuesTable = []
        for (let i = 0; i < this.dataShow.length; ++i) {
          this.valuesTable[i] = {
            special: this.dataShow[i].name,
            specialRange: this.dataArray2[i] * 100 + '%'
          }
        }
      })
    },
    async majorAnalyse() {
      await this.getPCAData()
      if (this.show === true) {
        const dom = this.$refs['myChart'] // 获取dom节点
        const myChart = echarts.init(dom) // 初始化echarts实例

        const option = {
          title: {
            text: '学生评教主成分分析',
            // subtext: 'Fake Data',
            left: 'center'
          },
          tooltip: {
            trigger: 'item'
          },
          legend: {
            orient: 'vertical',
            left: 'left'
          },
          xAxis: {
            data: ['PC1', 'PC2', 'PC3', 'PC4', 'PC5', 'PC6'] // X轴数据
          },
          yAxis: {}, // Y轴（自动根据数据生成刻度）
          series: [{
            name: '特征值', // 系列名称
            type: 'bar', // 图表类型：柱状图
            data: this.dataArray // 数据值
          }]
        }

        myChart.setOption(option)
      }
    }
  },
  mounted() {
    this.getCourseOptions()
  }
}
</script>

<style>
.chart-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}
.chart-box {
  height: 800px;
  width: 800px;
  border: 1px solid #eee;
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
</style>
